/*
 * @Author: czy
 * @Date: 2021-04-24 08:14:52
 * @LastEditTime: 2021-07-15 09:46:15
 */
#include "datetime.h"

#include "sys/container.h"

#include "../lib/hook.h"

int timer_on = 1;
static time_t TICK_TIMES = 0;

Zset tasks = newZset(hook);

/**
 * @description: Submit hook function.
 * @param h Hook.
 */
void submit(hook h)
{
    tasks.add(&tasks, 1, h);
}

/**
 * @description: Cancel hook function.
 * @param tskId Task ID.
 */
void cancel(int tskId)
{
    hook *h;
    for (int i = 0; i < tasks.length; i++)
    {
        h = (hook *)(tasks.get(&tasks, i));
        if (h->tskId == tskId)
        {
            tasks.delete(&tasks, i);
            break;
        }
    }
}

/**
 * @description: Update tasks.
 * @param h     Hook.
 * @param index Task number.
 */
static void update(hook *h, int index)
{
    if (h->times == 0)
    {
        tasks.delete(&tasks, index);
        return;
    }
    h->counter += 1000 / FREQUENCY;
    if (h->counter >= h->cycle)
    {
        if (timer_on)
        {
            h->func();
        }
        if (h->times > 0)
        {
            h->times--;
        }
        h->counter = 0;
    }
}

/**
 * @description: Hook function.
 */
void timer_hook(void)
{
    int index = 0;
    tasks.get(&tasks, 0);
    hook *task = (hook *)tasks.current->data;
    while ((task = (hook *)tasks.next(&tasks)) != NULL)
    {
        update(task, index);
        index++;
    }
}

/**
 * @description: Periodic clock interrupt.
 */
void tick(void)
{
    TICK_TIMES++;
    timer_hook();
}
